//
//  NSString+Category.m
//  
//
//  Created by lee on 2017/11/14.
//
//

#import "NSString+Category.h"
#import <sys/utsname.h>

#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
//#import <Security/>


#define kKeychainDeviceId @"kKeychainDeviceId"
#define kKeychainUUID @"kKeychainUUID"

@implementation NSString (Category)

+ (NSString *)numberLongString:(unsigned int)number
{
    NSString * str = @"0";
    if (number <= 1000)
    {
        str = [NSString  stringWithFormat:@"%d",number];
    }
    else  if (number<10000)
    {
        str = [NSString  stringWithFormat:@"%.1fk",number/1000.0];
    }
    else
    {
        str =[NSString  stringWithFormat:@"%.1fw",number/10000.0];
    }
    return str;
}

- (NSAttributedString *)emhtmlWithColor:(UIColor *)color {
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:self];
    NSRange begin;
    while ((begin = [attributedString.mutableString rangeOfString:@"<em>"]).location != NSNotFound) {
        NSRange end = [attributedString.mutableString rangeOfString:@"</em>"];
        if (end.location == NSNotFound) {
            return attributedString;
        }
        NSRange range = NSMakeRange(begin.location, end.location + end.length - begin.location);
        [attributedString addAttribute:NSForegroundColorAttributeName value:color range:range];
        [attributedString.mutableString replaceCharactersInRange:begin withString:@""];
        end = [attributedString.mutableString rangeOfString:@"</em>"];
        [attributedString.mutableString replaceCharactersInRange:end withString:@""];
    }
    return attributedString;
}

+ (NSString*)deviceVersion
{
    // 需要#import "sys/utsname.h"
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString *deviceString = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
    
    //CLog(@"%@",deviceString);
    if ([deviceString isEqualToString:@"iPhone1,1"])    return @"iPhone 1G";
    if ([deviceString isEqualToString:@"iPhone1,2"])    return @"iPhone 3G";
    if ([deviceString isEqualToString:@"iPhone2,1"])    return @"iPhone 3GS";
    if ([deviceString isEqualToString:@"iPhone3,1"])    return @"iPhone 4";
    if ([deviceString isEqualToString:@"iPhone3,2"])    return @"Verizon iPhone 4";
    if ([deviceString isEqualToString:@"iPhone4,1"])    return @"iPhone 4S";
    if ([deviceString isEqualToString:@"iPhone5,1"])    return @"iPhone 5";
    if ([deviceString isEqualToString:@"iPhone5,2"])    return @"iPhone 5";
    if ([deviceString isEqualToString:@"iPhone5,3"])    return @"iPhone 5C";
    if ([deviceString isEqualToString:@"iPhone5,4"])    return @"iPhone 5C";
    if ([deviceString isEqualToString:@"iPhone6,1"])    return @"iPhone 5S";
    if ([deviceString isEqualToString:@"iPhone6,2"])    return @"iPhone 5S";
    if ([deviceString isEqualToString:@"iPhone7,1"])    return @"iPhone 6 Plus";
    if ([deviceString isEqualToString:@"iPhone7,2"])    return @"iPhone 6";
    if ([deviceString isEqualToString:@"iPhone8,1"])    return @"iPhone 6s";
    if ([deviceString isEqualToString:@"iPhone8,2"])    return @"iPhone 6s Plus";
    if ([deviceString isEqualToString:@"iPhone9,1"] || [deviceString isEqualToString:@"iPhone9,3"])    return @"iPhone 7";
    if ([deviceString isEqualToString:@"iPhone9,2"] || [deviceString isEqualToString:@"iPhone9,4"])    return @"iPhone 7 Plus";
    if ([deviceString isEqualToString:@"iPhone10,1"] || [deviceString isEqualToString:@"iPhone10,4"])    return @"iPhone 8";
    if ([deviceString isEqualToString:@"iPhone10,2"] || [deviceString isEqualToString:@"iPhone10,5"])    return @"iPhone 8 Plus";
    if ([deviceString isEqualToString:@"iPhone10,3"] || [deviceString isEqualToString:@"iPhone10,6"])    return @"iPhone X";

    
    if ([deviceString isEqualToString:@"iPod1,1"])      return @"iPod Touch 1G";
    if ([deviceString isEqualToString:@"iPod2,1"])      return @"iPod Touch 2G";
    if ([deviceString isEqualToString:@"iPod3,1"])      return @"iPod Touch 3G";
    if ([deviceString isEqualToString:@"iPod4,1"])      return @"iPod Touch 4G";
    if ([deviceString isEqualToString:@"iPad1,1"])      return @"iPad";
    if ([deviceString isEqualToString:@"iPad2,1"])      return @"iPad 2 (WiFi)";
    if ([deviceString isEqualToString:@"iPad2,2"])      return @"iPad 2 (GSM)";
    if ([deviceString isEqualToString:@"iPad2,3"])      return @"iPad 2 (CDMA)";
    if ([deviceString isEqualToString:@"iPad3,4"])      return @"iPad 4 (WiFi)";
    if ([deviceString isEqualToString:@"i386"])         return @"Simulator";
    if ([deviceString isEqualToString:@"x86_64"])       return @"Simulator";
    
    //CLog(@"NOTE: Unknown device type: %@", deviceString);
    
    return deviceString;
}


+(NSString *)filterRichString:(NSString *)str
{
    __block NSString *string;
    if (([str containsString:@"<p>"]&&[str containsString:@"</p>"])||([str containsString:@"div"]&&[str containsString:@"div"]))
    {
        NSMutableAttributedString *attribute=[[NSMutableAttributedString alloc]initWithData:[str dataUsingEncoding:NSUnicodeStringEncoding] options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType} documentAttributes:nil error:nil];
        [attribute enumerateAttributesInRange:NSMakeRange(0, attribute.length) options:NSAttributedStringEnumerationReverse usingBlock:^(NSDictionary<NSString *,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
            NSString *temp=[attribute attributedSubstringFromRange:range].string;
            temp=[temp stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
            if (temp.length==0)
            {
                
            }
            else
            {
                string=[NSString stringWithFormat:@"%@%@",string.length==0?@"":string,temp];
                NSLog(@"%@,%ld",temp,(unsigned long)temp.length);
            }
        }];
        string=[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    }
    else
    {
        string=str;
    }
    return string;
}
+(BOOL)isNullOrWhiteSpace:(NSString *)string
{
    if (string==nil || [string isEqualToString:@""] || [string isEqual:[NSNull null]]) {
        return YES;
    }
    return NO;
}
+(NSString*)filterAnySpecialCharactersInString:(NSString *)string
{
    NSString* waitingForFilterString=string;
    NSCharacterSet* set=[NSCharacterSet characterSetWithCharactersInString:@"@／：；（）¥「」＂、[]{}#%-*+=_\\|~＜＞$€^•'@#$%^&*()_+'\" <p></p>"];
    NSString* filterString=[waitingForFilterString stringByTrimmingCharactersInSet:set];
    return filterString;
}


+(NSString*)finallyDateString:(NSString*)dateString
{
    NSDateFormatter * formatter2 = [[NSDateFormatter alloc]init];
    [formatter2 setDateFormat:@"yyyy-MM-dd"];
    NSDate * date3 = [formatter2 dateFromString:dateString];
    [formatter2 setDateFormat:@"MM月dd日"];
    NSString * time= [formatter2 stringFromDate:date3];
    return time;
}

-(BOOL)isRichString
{
    if (([self containsString:@"<p"]&&[self containsString:@"</p>"])||([self containsString:@"div"]&&[self containsString:@"div"])||([self containsString:@"<img"]&&[self containsString:@">"])||([self containsString:@"<li>"]&&[self containsString:@"</li>"])||([self containsString:@"<ol>"]&&[self containsString:@"</ol>"])||[self containsString:@"<br>"])
    {
        return YES;
    }
    return NO;
}



////////////////////////////////////////


- (NSString *)md5
{
    const char *cStr = [self UTF8String];
    unsigned char result[16];
    
    //    去除警告(CC_LONG)
    CC_MD5(cStr, (CC_LONG)strlen(cStr), result); // This is the md5 call
    return [NSString stringWithFormat:
            @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ];
}


- (NSString*) sha1
{
    const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:self.length];
    
    uint8_t digest[CC_SHA1_DIGEST_LENGTH];
    
    CC_SHA1(data.bytes, (CC_LONG)data.length, digest);
    
    NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
    
    for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
        [output appendFormat:@"%02x", digest[i]];
    
    return output;
}

- (NSString*) sha224
{
    const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:self.length];
    
    uint8_t digest[CC_SHA224_DIGEST_LENGTH];
    
    CC_SHA224(data.bytes, (CC_LONG)data.length, digest);
    
    NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA224_DIGEST_LENGTH * 2];
    
    for(int i = 0; i < CC_SHA224_DIGEST_LENGTH; i++)
        [output appendFormat:@"%02x", digest[i]];
    
    return output;
}

- (NSString*) sha256
{
    const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:self.length];
    
    uint8_t digest[CC_SHA256_DIGEST_LENGTH];
    
    CC_SHA256(data.bytes, (CC_LONG)data.length, digest);
    
    NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
    
    for(int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++)
        [output appendFormat:@"%02x", digest[i]];
    
    return output;
}

- (NSString*) sha384
{
    const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:self.length];
    
    uint8_t digest[CC_SHA384_DIGEST_LENGTH];
    
    CC_SHA384(data.bytes, (CC_LONG)data.length, digest);
    
    NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA384_DIGEST_LENGTH * 2];
    
    for(int i = 0; i < CC_SHA384_DIGEST_LENGTH; i++)
        [output appendFormat:@"%02x", digest[i]];
    
    return output;
}

- (NSString*) sha512
{
    const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:self.length];
    
    uint8_t digest[CC_SHA512_DIGEST_LENGTH];
    
    CC_SHA512(data.bytes, (CC_LONG)data.length, digest);
    
    NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA512_DIGEST_LENGTH * 2];
    
    for(int i = 0; i < CC_SHA512_DIGEST_LENGTH; i++)
        [output appendFormat:@"%02x", digest[i]];
    
    return output;
}

-(NSString *) base64{
    NSData* originData = [self dataUsingEncoding:NSUTF8StringEncoding];
    NSString * encodeResult = [originData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    return encodeResult;
}

-(NSString *) decodeBase64{
    NSData* decodeData = [[NSData alloc] initWithBase64EncodedString:self options:0];
    NSString* decodeStr = [[NSString alloc] initWithData:decodeData encoding:NSUTF8StringEncoding];
    return decodeStr;
}
///////////////////////////////////


//判断内容是否全部为空格  yes 全部为空格  no 不是
+ (BOOL) isEmpty:(NSString *) str{
    if (!str) {
        return YES;
    } else {
        NSCharacterSet *set = [NSCharacterSet whitespaceAndNewlineCharacterSet];
        
        if ([str isKindOfClass:[NSNull class]])
        {
            return YES;
        }
        NSString *trimedString = [str stringByTrimmingCharactersInSet:set];
        
        if ([trimedString length] == 0) {
            return YES;
        } else {
            return NO;
        }
    }
}



+ (NSString *)uuid{
    CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
    CFStringRef strUuid = CFUUIDCreateString(kCFAllocatorDefault,uuid);
    NSString * str = [NSString stringWithString:(__bridge NSString *)strUuid];
    CFRelease(strUuid);
    CFRelease(uuid);
    return  str;
    
}

///过滤html标签
+ (NSString *)filterHTML:(NSString *)html
{
    NSScanner * scanner = [NSScanner scannerWithString:html];
    NSString * text = nil;
    while([scanner isAtEnd]==NO)
    {
        [scanner scanUpToString:@"<" intoString:nil];
        [scanner scanUpToString:@">" intoString:&text];
        html = [html stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%@>",text] withString:@""];
    }
    
    ///<head><style>img{max-width:%.0lfpx !important;height: auto!important;}</style></head>
    NSScanner * scanner2 = [NSScanner scannerWithString:html];
    NSString * text2 = nil;
    while ([scanner2 isAtEnd] == NO)
    {
        [scanner2 scanUpToString:@"img{max-width:" intoString:nil];
        [scanner2 scanUpToString:@"important;}" intoString:&text2];
        html = [html stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%@important;}",text2] withString:@""];
    }
    
    /// 网页空格
    html = [html stringByReplacingOccurrencesOfString:@"&nbsp;" withString:@" "];
    
    return html;
}
///////////////////////////////
//生成并返回sign
//$params = [
//           't'   => $time,//当前时间的时间戳
//           'key' => $key,//$key = nXCXa7jO2jbYtWL5SqCcrMBEF3dMXKt2
//           ];
//
////按键排序
//ksort($params);
//
////拼接
//$str = http_build_query($params);
//
////MD5加密，生成sign
//$str = md5($str);
+(NSString *)getSign:(NSString *)timestamp key:(NSString *)key
{
    NSMutableDictionary * mDic = [[NSMutableDictionary alloc] init];
    [mDic setObject:timestamp forKey:@"t"];
    [mDic setObject:key forKey:@"key"];
    NSString * paramString = [NSString stringWithFormat:@"key=%@&t=%@", key, timestamp];
    return [NSString md5WithString:paramString];
}
//String sign = Md5.getMd5(String.valueOf(time) + String.valueOf(info.getId()) + "nCXqd4hvnDXluUcVbpkicxytTMNpo1V5");
+(NSString *)getBoySign:(NSString *)timestamp getID:(NSString *)Id key:(NSString *)key
{
    NSString * paramString = [NSString stringWithFormat:@"%@%@%@",timestamp,Id,key];
    return [NSString md5WithString:paramString];
}

//md5加密
+(NSString *)md5WithString:(NSString *)string
{
    const char *cStr = [string UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cStr, (uint32_t)strlen(cStr), result);
    return [NSString stringWithFormat:
            @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]
            ];
}

/// 修正精度
+(NSString *)reviseString:(NSString *)str
{
    //直接传入精度丢失有问题的Double类型
    double conversionValue = [str doubleValue];
    NSString *doubleString = [NSString stringWithFormat:@"%lf", conversionValue];
    NSDecimalNumber *decNumber = [NSDecimalNumber decimalNumberWithString:doubleString];
    return [decNumber stringValue];
}

- (NSString *)reviseString
{
    return [NSString reviseString:self];
}

- (NSString *)getRealPrice
{
    return [NSString getRealPrice:self];
}

/// 价格字符串去0
+ (NSString *)getRealPrice:(NSString *)price
{
    if ([price isKindOfClass:[NSString class]])
    {
        price = [self reviseString:price];
        CGFloat floatPrice = [price floatValue];
        unsigned int intergerPrice = (unsigned int)floatPrice;
        
        if (intergerPrice == floatPrice)
        {
            return [NSString stringWithFormat:@"%.0f",floatPrice];
        }
        else if ([price componentsSeparatedByString:@"."].count == 2 )
        {
            if ([price hasSuffix:@"0"]) {
                return [NSString stringWithFormat:@"%.1f",floatPrice];
            }
            return price;
        }
        else{
//            return price;
            return [NSString stringWithFormat:@"%.1f",floatPrice];
        }
    }
    /// 非string
    return [NSString stringWithFormat:@"%.2f",[price floatValue]];
}


/// 返回label高度
- (CGFloat)getLabelHeightWithWidth:(CGFloat)width Font:(UIFont *)font
{
    NSDictionary *attrs = @{NSFontAttributeName : font};
    CGSize maxSize = CGSizeMake(width, MAXFLOAT);
    
    CGSize size = [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingUsesFontLeading attributes:attrs context:nil].size;
    
    return size.height;
}

/// 返回label高度，最小高度为minLabelheight
- (CGFloat)getLabelHeightWithMinLabelHeight:(CGFloat)minLabelheight Width:(CGFloat)width Font:(UIFont *)font
{
    return MAX(minLabelheight, [self getLabelHeightWithWidth:width Font:font]);
}

/// 返回label对比minLabelheight增加高度（大于0）
- (CGFloat)getGainedLabelHeightWithMinLabelHeight:(CGFloat)minLabelheight Width:(CGFloat)width Font:(UIFont *)font
{
    CGFloat divHeight = [self getLabelHeightWithMinLabelHeight:minLabelheight Width:width Font:font] - minLabelheight;
    
    return  0 < divHeight ? divHeight : 0;
}

/// 返回cell的高度,minLabelheight为label的最小高度，minCellheight为cell的最小高度
- (CGFloat)getCellHeightWithMinCellHeight:(CGFloat)minCellheight MinLabelHeight:(CGFloat)minLabelheight  Width:(CGFloat)width Font:(UIFont *)font
{
    
    return minCellheight + [self getGainedLabelHeightWithMinLabelHeight:minLabelheight Width:width Font:font];
}

/// 获取字符串长
- (CGFloat)getStringWidthWithHeight:(CGFloat)height Font:(UIFont *)font
{
    NSDictionary *attrs = @{NSFontAttributeName : font};
    CGSize maxSize = CGSizeMake(MAXFLOAT, height);
    
    CGSize size = [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingUsesFontLeading attributes:attrs context:nil].size;
    
    return size.width;
}

- (NSCalendar *)currentCalendar {
    if ([NSCalendar respondsToSelector:@selector(calendarWithIdentifier:)]) {
        return [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
    }
    return [NSCalendar currentCalendar];
}

/// 秒 ——》00:12
- (NSString *)audioPlayLength
{
    int ti = (int)(self.floatValue +0.5);
    int seconds = ti % 60;
    int minutes = (ti / 60);
    return [NSString stringWithFormat:@"%02d:%02d", minutes, seconds];
}


+ (NSString *)getCountdownStringWithTimeIntervalSinceNow:(NSTimeInterval)timeInterval
{
    if (timeInterval <= 0)
    {
        return @"00:00:00";
    }
    int ti = (int)(timeInterval +0.5);
    int seconds = ti % 60;
    int minutes = (ti / 60) % 60;
    int hours = (ti / 60 / 60) % 24;
    int days = (ti / 60 / 60) / 24;
    if (days>0)
    {
        return [NSString stringWithFormat:@"%d天 %02d:%02d:%02d", days, hours , minutes, seconds];
    }
    return [NSString stringWithFormat:@"%02d:%02d:%02d", hours , minutes, seconds];
    
}

/// 是否有链接
- (BOOL)textCheckingTypeLink
{
    NSDataDetector * detector = [NSDataDetector dataDetectorWithTypes: NSTextCheckingTypeLink error:nil];
    NSTextCheckingResult * match =[detector firstMatchInString:self options:0 range:NSMakeRange(0, [self length])];
    NSRange matchRange = [match range];
    return matchRange.length;
}

/// 第一个链接
- (NSURL *)textMatchFirstLink
{
    NSDataDetector * detector = [NSDataDetector dataDetectorWithTypes: NSTextCheckingTypeLink error:nil];
    NSTextCheckingResult * match =[detector firstMatchInString:self options:0 range:NSMakeRange(0, [self length])];
    return [match URL];
}

/// 2行，第index个字符换行
- (NSString *)line2AtIndex:(unsigned int)index
{
    if (self.length > index)
    {
        NSString * first = [self substringToIndex:index];
        NSString * second = [self substringFromIndex:index];
        if (second.length==0)
        {
            return first;
        }
        else
        {
            return [NSString stringWithFormat:@"%@\n%@",first,second];
        }
    }
    return self;
}

+ (NSString *)line2AtIndex:(unsigned int)index withString:(NSString *)string
{
    return [string line2AtIndex:index];
}

/// 传入宽度，得到近似宽度的空格字符
+ (NSString *)getSpaceStringWithSpaceWidth:(CGFloat)width height:(CGFloat)height font:(UIFont *)font
{
    CGFloat kw = [@" " getStringWidthWithHeight:height Font:font];
    unsigned int kcount = (width)/kw;
    NSString * ks = @" ";
    for (unsigned int i = 0; i < kcount; i++)
    {
        ks = [NSString stringWithFormat:@" %@",ks];
    }
    return ks;
}
///自动缓存文件位置
+(NSString *)getAudioSaveFilePath
{
    NSString *path=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
    NSString *dirctory=[path stringByAppendingPathComponent:@"/HuaZhenApp"];
    if (![[NSFileManager defaultManager] fileExistsAtPath:dirctory])
    {
        [[NSFileManager defaultManager] createDirectoryAtPath:dirctory withIntermediateDirectories:YES attributes:nil error:nil];
    }
    return [dirctory stringByAppendingPathComponent:@"/emtionTalkAudio.mp3"];
}

@end
